//---------------------------------------------------------------------------

#include "vcl_stl.h"
#pragma hdrstop

#include "h_base.h"
#include "h_xml.h"
#include "h_global.h"
using namespace h_base;
using namespace h_xml;

#include "h_g.h"
#include "h_stage.h"
#include "h_server.h"

#include "t_listform.h"
#include "h_portal.h"
#include "t_mainform.h"
#include "h_i18n.h"

#include "t_listform.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TListForm *ListForm;
//---------------------------------------------------------------------------
__fastcall TListForm::TListForm(TComponent* Owner)
   : TForm(Owner)
{
   CommandFlag = false;
}
//---------------------------------------------------------------------------
void __fastcall TListForm::CheckBoxAllClick(TObject *Sender)
{
   if ( CheckBoxAll->Checked )
   {
      CheckBoxWaiting->Enabled = false;
      CheckBoxRunning->Enabled = false;
      CheckBoxSkipped->Enabled = false;
      CheckBoxFail->Enabled = false;
      CheckBoxSuccess->Enabled = false;
      CheckBoxUnknown->Enabled = false;
   }
   else
   {
      CheckBoxWaiting->Enabled = true;
      CheckBoxRunning->Enabled = true;
      CheckBoxSkipped->Enabled = true;
      CheckBoxFail->Enabled = true;
      CheckBoxSuccess->Enabled = true;
      CheckBoxUnknown->Enabled = true;
   }
}
//---------------------------------------------------------------------------

void __fastcall TListForm::Clear()
{
   JobMap.clear();
   JobList.clear();
   StringGrid1->RowCount = 2;
   StringGrid1->Rows[0]->Strings[0] = UTF8String(h_g::I18nString("t_listform:NAME"));
   StringGrid1->Rows[0]->Strings[1] = UTF8String(h_g::I18nString("t_listform:PART"));
   StringGrid1->Rows[0]->Strings[2] = UTF8String(h_g::I18nString("t_listform:STATUS"));
   StringGrid1->Rows[0]->Strings[3] = UTF8String(h_g::I18nString("t_listform:START_TIME"));
   StringGrid1->Rows[0]->Strings[4] = UTF8String(h_g::I18nString("t_listform:END_TIME"));
   StringGrid1->Rows[0]->Strings[5] = UTF8String(h_g::I18nString("t_listform:ELAPSED"));

   if ( CommandFlag )
   {
      StringGrid1->Rows[0]->Strings[6] = UTF8String(h_g::I18nString("t_listform:COMMAND"));
   }
   else
   {
      StringGrid1->Rows[0]->Strings[6] = UTF8String(h_g::I18nString("t_listform:DESCRIPTION"));
   }

   StringGrid1->Rows[0]->Strings[7] = UTF8String(h_g::I18nString("t_listform:TAG"));
   StringGrid1->Rows[0]->Strings[8] = UTF8String(h_g::I18nString("t_listform:RUNNING"));
   StringGrid1->Rows[0]->Strings[9] = UTF8String(h_g::I18nString("t_listform:WAITING"));
   StringGrid1->Rows[0]->Strings[10] = UTF8String(h_g::I18nString("t_listform:SUCCESS"));
   StringGrid1->Rows[0]->Strings[11] = UTF8String(h_g::I18nString("t_listform:FAIL"));

   for ( int i = 0; i < 12; i++ )
   {
      StringGrid1->Rows[1]->Strings[i] = "";
   }
}

void __fastcall TListForm::Reload()
{
   JobMap.clear();
   MainForm->SaveToJobList(JobMap);
   AssignRows();
}

void __fastcall TListForm::AssignRows()
{
   map<UTF8String, HJobListInfo> NewJobList;

   Filter(NewJobList);

   bool AllFlag = NewJobList.size() != JobList.size();

   if ( NewJobList.empty() )
   {
      StringGrid1->RowCount = 2;
      for ( int i = 0; i < 12; i++ )
      {
         StringGrid1->Rows[1]->Strings[i] = "";
      }
   }
   else
   {
      StringGrid1->RowCount = NewJobList.size() + 1;
      int i;
      map<UTF8String, HJobListInfo>::iterator Iter;
      map<UTF8String, HJobListInfo>::iterator IterNew;
      for ( Iter = JobList.begin(), IterNew = NewJobList.begin(), i = 1;
            i <= NewJobList.size(); i++, IterNew++ )
      {
         const HJobListInfo &NewInfo = IterNew->second;
         if ( AllFlag )
         {
            AssignOneRow(i, NewInfo);
         }
         else
         {
            const HJobListInfo &Info = Iter->second;
            if ( Info.Name != NewInfo.Name ||
                 Info.Partition != NewInfo.Partition ||
                 Info.Status != NewInfo.Status ||
                 Info.StartTime != NewInfo.StartTime ||
                 Info.EndTime != NewInfo.EndTime ||
                 Info.Command != NewInfo.Command ||
                 Info.Description != NewInfo.Description)
            {
               AssignOneRow(i, NewInfo);
            }
            Iter++;
         }
      }
   }

   JobList = NewJobList;
   UpdateButtons(StringGrid1->Selection.Top);
}

void __fastcall TListForm::AssignOneRow(int RowIdx, const HJobListInfo &Info)
{
   StringGrid1->Rows[RowIdx]->Strings[0] = Info.Name;

   vector<string> StrVec;

   SplitString(Info.Partition.c_str(), '/', StrVec, true);

   if ( StrVec.size() == 5 )
   {
      StringGrid1->Rows[RowIdx]->Strings[1] = StrVec[4].c_str();
      StringGrid1->Rows[RowIdx]->Strings[8] = StrVec[0].c_str();
      StringGrid1->Rows[RowIdx]->Strings[9] = StrVec[1].c_str();
      StringGrid1->Rows[RowIdx]->Strings[10] = StrVec[2].c_str();
      StringGrid1->Rows[RowIdx]->Strings[11] = StrVec[3].c_str();
   }
   else
   {
      StringGrid1->Rows[RowIdx]->Strings[1] = "";
      StringGrid1->Rows[RowIdx]->Strings[8] = "";
      StringGrid1->Rows[RowIdx]->Strings[9] = "";
      StringGrid1->Rows[RowIdx]->Strings[10] = "";
      StringGrid1->Rows[RowIdx]->Strings[11] = "";
   }

   StringGrid1->Rows[RowIdx]->Strings[2] = Info.Status;
   StringGrid1->Rows[RowIdx]->Strings[3] = FormatDateTime(Info.StartTime);
   StringGrid1->Rows[RowIdx]->Strings[4] = FormatDateTime(Info.EndTime);
   StringGrid1->Rows[RowIdx]->Strings[5] = Info.ElapsedTime;

   if ( CommandFlag )
   {
      StringGrid1->Rows[RowIdx]->Strings[6] = Info.Command;
   }
   else
   {
      StringGrid1->Rows[RowIdx]->Strings[6] = Info.Description;
   }

   StringGrid1->Rows[RowIdx]->Strings[7] = Info.Tag;
}

void __fastcall TListForm::Filter(map<UTF8String, HJobListInfo> &NewJobList)
{
   UTF8String NameFilter = EditText->Text.Trim().UpperCase();
   UTF8String StartTime1Filter = GetDateTime(UTF8String(EditStartTime1->Text).c_str());
   UTF8String StartTime2Filter = GetDateTime(UTF8String(EditStartTime2->Text).c_str());
   UTF8String EndTime1Filter = GetDateTime(UTF8String(EditEndTime1->Text).c_str());
   UTF8String EndTime2Filter = GetDateTime(UTF8String(EditEndTime2->Text).c_str());
   UTF8String ElapsedTimeFilter;

   if ( EditElapsedTime->Text.Trim() != "" )
   {
      int Seconds;
      vector<string> StrVec;
      char TmpStr[80 + 1];
      SplitString(UTF8String(EditElapsedTime->Text).c_str(), ':', StrVec);
      switch ( StrVec.size() )
      {
      case 0 :
         Seconds = 0;
         break;
      case 1 :
         Seconds = StrToInt(StrVec[0].c_str());
         break;
      case 2 :
         Seconds = StrToInt(StrVec[0].c_str()) * 60 +
            StrToInt(StrVec[1].c_str());
         break;
      default :
         Seconds = StrToInt(StrVec[0].c_str()) * 3600 +
            StrToInt(StrVec[1].c_str()) * 60 +
            StrToInt(StrVec[2].c_str());
         break;
      }
      snprintf(TmpStr, 80, "%02d:%02d:%02d", Seconds / 3600,
         Seconds % 3600 / 60, Seconds % 60);
      ElapsedTimeFilter = TmpStr;
   }

   NewJobList.clear();

   for ( map<UTF8String, HJobListInfo>::iterator Iter = JobMap.begin();
         Iter != JobMap.end(); Iter++ )
   {
      const HJobListInfo &Info = Iter->second;
      if ( NameFilter != "" && Info.Name.Pos(NameFilter) == 0 &&
           Info.CommandUpper.Pos(NameFilter) == 0 &&
           Info.Tag.Pos(NameFilter) == 0 )
      {
         continue;
      }
      if ( !CheckBoxAll->Checked )
      {
         bool Ok = false;
         if ( CheckBoxWaiting->Checked && Info.Status == "WAITING" )
         {
            Ok = true;
         }
         if ( CheckBoxRunning->Checked &&
              ( Info.Status == "RUNNING" || Info.PartRunning ) )
         {
            Ok = true;
         }
         if ( CheckBoxSkipped->Checked &&
              ( Info.Status == "SKIPPED" || Info.PartSkipped ) )
         {
            Ok = true;
         }
         if ( CheckBoxFail->Checked &&
              ( Info.Status == "FAIL" || Info.PartFail ) )
         {
            Ok = true;
         }
         if ( CheckBoxSuccess->Checked && Info.Status == "SUCCESS" )
         {
            Ok = true;
         }
         if ( CheckBoxUnknown->Checked &&
             ( Info.Status == "UNKNOWN" || Info.PartUnknown ) )
         {
            Ok = true;
         }
         if ( !Ok )
         {
            continue;
         }
      }
      if ( StartTime1Filter != "00000000000000" && Info.StartTime < StartTime1Filter )
      {
         continue;
      }
      if ( StartTime2Filter != "00000000000000" && Info.StartTime > StartTime2Filter )
      {
         continue;
      }
      if ( EndTime1Filter != "00000000000000" && Info.EndTime < EndTime1Filter )
      {
         continue;
      }
      if ( EndTime2Filter != "00000000000000" && Info.EndTime > EndTime2Filter )
      {
         continue;
      }
      if ( ElapsedTimeFilter != "" && Info.ElapsedTime < ElapsedTimeFilter )
      {
         continue;
      }
      NewJobList[Info.Name] = Info;
   }
}

void __fastcall TListForm::ButtonFilterClick(TObject *Sender)
{
   AssignRows();
}
//---------------------------------------------------------------------------

void __fastcall TListForm::UpdateButtons(int Row)
{
   UTF8String JobName = StringGrid1->Rows[Row]->Strings[0];
   HStage *Stage = MainForm->FindControlByName(JobName);
   HBatchIcon *Batch = MainForm->Portal->CurrentBatch;

   if ( Stage == NULL )
   {
      ButtonProperty->Enabled = false;
      ButtonViewLog->Enabled = false;
      ButtonGotoThisGroup->Enabled = false;
      ButtonSkip->Enabled = false;
      ButtonRestore->Enabled = false;
      ButtonRerun->Enabled = false;
      ButtonStop->Enabled = false;
      ButtonRestart->Enabled = false;
      return;
   }

   ButtonProperty->Enabled = true;
   ButtonViewLog->Enabled = !Batch->Outline.Offline && Stage->CanViewLog();
   ButtonGotoThisGroup->Enabled = true;

   ButtonSkip->Enabled = ( MainForm->CurrentBatchIsRunning() &&
      Stage->CanSkip() );
   ButtonRestore->Enabled = ( MainForm->CurrentBatchIsRunning() &&
      Stage->CanRestore() );
   ButtonRerun->Enabled = ( MainForm->CurrentBatchIsRunning() &&
      Stage->CanRerun() );
   ButtonStop->Enabled = ( MainForm->CurrentBatchIsRunning() &&
      Stage->CanStop() );
   ButtonRestart->Enabled = MainForm->CurrentBatchEnableRestart() &&
      ( ( MainForm->CurrentBatchIsRunning() ||
      MainForm->CurrentBatchIsCompleted() ) &&
      Stage->CanRestart() );
}

void __fastcall TListForm::StringGrid1SelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
   UpdateButtons(ARow);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonPropertyClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];
   HStage *Stage = MainForm->FindControlByName(JobName);

   if ( Stage == NULL )
   {
      return;
   }

   Stage->EditProperty();
}
//---------------------------------------------------------------------------


void __fastcall TListForm::ButtonViewLogClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->ViewLog(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonSkipClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->Skip(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonRestoreClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->Restore(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonRerunClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->Rerun(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonStopClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->Stop(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonRestartClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->Restart(JobName);
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonGotoThisGroupClick(TObject *Sender)
{
   UTF8String JobName = StringGrid1->Rows[StringGrid1->Selection.Top]->Strings[0];

   if ( JobName == "" )
   {
      return;
   }

   MainForm->GotoGroupAndFocusToJob(JobName);
   Close();
}
//---------------------------------------------------------------------------


void __fastcall TListForm::ButtonRefreshClick(TObject *Sender)
{
   MainForm->Refresh();
}
//---------------------------------------------------------------------------



void __fastcall TListForm::ButtonDescriptionClick(TObject *Sender)
{
   CommandFlag = !CommandFlag;

   if ( CommandFlag )
   {
      StringGrid1->Rows[0]->Strings[6] = UTF8String(h_g::I18nString("t_listform:COMMAND"));
   }
   else
   {
      StringGrid1->Rows[0]->Strings[6] = UTF8String(h_g::I18nString("t_listform:DESCRIPTION"));
   }

   int RowIdx = 1;

   for ( map<UTF8String, HJobListInfo>::iterator Iter = JobList.begin();
         RowIdx <= JobList.size(); RowIdx++, Iter++ )
   {
      const HJobListInfo &Info = Iter->second;
      if ( CommandFlag )
      {
         StringGrid1->Rows[RowIdx]->Strings[6] = Info.Command;
      }
      else
      {
         StringGrid1->Rows[RowIdx]->Strings[6] = Info.Description;
      }
   }
}
//---------------------------------------------------------------------------

void __fastcall TListForm::ButtonSaveClick(TObject *Sender)
{
   SaveDialog1->DefaultExt = "csv";
   SaveDialog1->Filter =
      "Comma-Separated Values (*.csv)|*.csv|All files (*.*)|*.*";
   SaveDialog1->FilterIndex = 1;

   if ( SaveDialog1->InitialDir == "" )
   {
      SaveDialog1->InitialDir = h_g::BaseDir + "bats";
   }

   SaveDialog1->Options = TOpenOptions() << ofOverwritePrompt
      << ofEnableSizing;
   SaveDialog1->Title = UTF8String(h_g::I18nString("t_downloadform:SAVE_FILE_AS"));

   if( !SaveDialog1->Execute() )
   {
      return;
   }

   FILE *f = _wfopen(SaveDialog1->FileName.c_str(), L"wt");

   if ( f == NULL )
   {
      UTF8String TmpStr;
      h_g::ShowMessage(TmpStr.sprintf("Can not create %s", SaveDialog1->FileName.c_str()));
   }

   for ( int i = 0; i < StringGrid1->RowCount; i++ )
   {
      vector<UTF8String> StrVec;

      for ( int j = 0; j < 12; j++ )
      {
         StrVec.push_back(StringGrid1->Rows[i]->Strings[j]);
      }

      fprintf(f, "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
         StrVec[0].c_str(), StrVec[1].c_str(), StrVec[2].c_str(),
         StrVec[3].c_str(), StrVec[4].c_str(), StrVec[5].c_str(),
         StrVec[7].c_str(), StrVec[8].c_str(), StrVec[9].c_str(),
         StrVec[10].c_str(), StrVec[11].c_str(),
         StrVec[6].c_str());
   }

   fclose(f);
}

